package im.yisme.view.activities;

import java.util.ArrayList;
import java.util.Iterator;

import im.yisme.R;
import im.yisme.controler.MusicCtrl;
import im.yisme.controler.service.CtrlServiceProvider;
import im.yisme.controler.service.GameCtrlService;
import im.yisme.controler.service.LyricsCtrlService;
import im.yisme.controler.service.MusicCtrlService;
import im.yisme.controler.service.RecordCtrlService;
import im.yisme.model.service.GameSystemService;
import im.yisme.model.service.ModelServiceProvider;
import im.yisme.view.ViewController;
import im.yisme.view.service.GameActivityService;
import im.yisme.view.service.ViewService;
import im.yisme.view.service.ViewServiceProvider;
import im.yisme.view.ui.GameView;
import im.yisme.view.ui.RecordView;
import im.yisme.view.ui.animation.Bloom;
import im.yisme.view.ui.animation.Clock;
import im.yisme.view.ui.component.OnClickListener;
import im.yisme.view.ui.component.YButton;
import im.yisme.view.ui.util.ButtonEventListener;
import im.yisme.view.ui.util.UIparams;
import im.yisme.vo.LyricsActionVO;
import im.yisme.vo.LyricsVO;
import im.yisme.vo.MusicVO;
import im.yisme.vo.RawActionVO;
import android.R.integer;
import android.app.Activity;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.PointF;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.RemoteViews.ActionException;

public class GameActivity extends Activity implements GameActivityService{
	
	private GameCtrlService gameCtrl;
	private GameSystemService gameModel;
	private ViewService viewCtrl;
	
	//时刻控制
	private long startMoment,pauseMoment;
	public boolean pause;
	private static final int PAUSE_PAULING_INTERVAL=500;
	private static final int PAULING_INTERVAL=2;
	private MomentControl momentControlThread;
		
	//UI
	private GameView view;
	private YButton pauseButton,quitButton,resumeButton,restartButton;
	private ButtonEventListener buttonEventListener;
		
		
	//音乐
	private MediaPlayer player;

	//音符
	private ArrayList<LyricsActionVO> toPlayLyricsList;
	
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		init();
			
	}
	
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		//先交给ButtonEventListener做检测
				
		if(buttonEventListener.onButtonEvent(event)) return false;

		
		if(pause) return false;
		
		int moment = (int) (System.currentTimeMillis() - startMoment);

		RawActionVO rawAction;
		switch (event.getAction()) {
		case MotionEvent.ACTION_POINTER_DOWN:

			rawAction = new RawActionVO(RawActionVO.DOWN, moment);
			rawAction.x1 = event.getX(1);
			rawAction.y1 = event.getY(1);

			gameCtrl.input(rawAction);
			break;
			
		case MotionEvent.ACTION_POINTER_UP:

			rawAction = new RawActionVO(RawActionVO.UP, moment);
			rawAction.x1 = event.getX(0);
			rawAction.y1 = event.getY(0);

			gameCtrl.input(rawAction);
			break;
			
		case MotionEvent.ACTION_DOWN:

			rawAction = new RawActionVO(RawActionVO.DOWN, moment);
			rawAction.x1 = event.getX(0);
			rawAction.y1 = event.getY(0);

			gameCtrl.input(rawAction);
			break;
			
		case MotionEvent.ACTION_MOVE:

			rawAction = new RawActionVO(RawActionVO.MOVE, moment);
			rawAction.x1 = event.getX(0);
			rawAction.y1 = event.getY(0);
			if(event.getPointerCount()>1){
				rawAction.x2 = event.getX(1);
				rawAction.y2 = event.getY(1);
			}

			
			
			gameCtrl.input(rawAction);
			
			//view.addNewMovePoint(new PointF(event.getX(), event.getY()));
			  
			break;
			
		case MotionEvent.ACTION_UP:

			rawAction = new RawActionVO(RawActionVO.UP, moment);
			rawAction.x1 = event.getX(0);
			rawAction.y1 = event.getY(0);

			
			gameCtrl.input(rawAction);
			
			view.setTrackBegin();
			break;
			
		case MotionEvent.ACTION_POINTER_2_DOWN:

			rawAction = new RawActionVO(RawActionVO.DOWN, moment);
			rawAction.x1 = event.getX(1);
			rawAction.y1 = event.getY(1);

			gameCtrl.input(rawAction);
			break;
			
		case MotionEvent.ACTION_POINTER_2_UP:

			rawAction = new RawActionVO(RawActionVO.UP, moment);
			rawAction.x1 = event.getX(1);
			rawAction.y1 = event.getY(1);

			gameCtrl.input(rawAction);
			break;
			
		default:
			return false;
		}

		return true;
	}
	
	//---------------------------------------------------------
	// 时刻控制线程,用于派发音符UI，定时从Model更新数据，音符过期检测
	class MomentControl extends Thread{
		private boolean isRunning;
		
		public MomentControl(){
			isRunning=true;
		}
		public void run(){
		
			try {
				
			while(isRunning){
				while(pause) Thread.sleep(PAUSE_PAULING_INTERVAL);
				//音符UI派发
				while(true){
					if(toPlayLyricsList != null && toPlayLyricsList.size()==0) {
						ArrayList<LyricsActionVO> tempList=gameModel.getNewLyrics();
						
						if(tempList!=null){
							Iterator<LyricsActionVO> it=tempList.iterator();
							while (it.hasNext()) {
								LyricsActionVO lyricsActionVO =  it.next();
								toPlayLyricsList.add(lyricsActionVO);
							}
						}
						else {
							toPlayLyricsList=null;
						}					
					}
					
					if(toPlayLyricsList == null) {
						break;				
					}
					
					LyricsActionVO lyrics=toPlayLyricsList.get(0);
					boolean played=false;
					
					switch (lyrics.getType()) {
					case LyricsActionVO.TAP:
						 if((System.currentTimeMillis()-startMoment)>(lyrics.getTime()-Clock.DURATION)){
							 view.clock(lyrics.getPoint(), lyrics.getTime()+startMoment);
							 toPlayLyricsList.remove(0);
							 played=true;
						 }						 
						break;
					case LyricsActionVO.DRAG:
						switch (lyrics.getConnectionType()) {
						case LyricsActionVO.BEGIN_POINT:
							if((System.currentTimeMillis()-startMoment)>(lyrics.getTime()-Bloom.DURATION)){
								LyricsActionVO nextLyrics=toPlayLyricsList.get(1);
								
								view.bloom(lyrics.getPoint(), lyrics.getTime()+startMoment, lyrics.isActive(), false);
								int index = 1;
								while(nextLyrics.getConnectionType() != LyricsActionVO.END_POINT){
									index++;
									nextLyrics = toPlayLyricsList.get(index);
								}
								int points[] = new int[index+1];
								for(int i=0;i<index+1;i++){
									points[i] = toPlayLyricsList.get(i).getPoint();
									 
								}

								view.comet(points, nextLyrics.getTime()+startMoment, lyrics.isActive());

								toPlayLyricsList.remove(0);
								played=true;
							}
							break;
						case LyricsActionVO.LINK_POINT:
							if((System.currentTimeMillis()-startMoment)>(lyrics.getTime()-Bloom.DURATION)){					

								view.bloom(lyrics.getPoint(), lyrics.getTime()+startMoment, lyrics.isActive(), true);
								if(!lyrics.isActive()) view.dieCurrentLine();
								
								toPlayLyricsList.remove(0);
								played=true;
							}
							break;
						case LyricsActionVO.END_POINT:

							if((System.currentTimeMillis()-startMoment)>(lyrics.getTime()-Bloom.DURATION)){		
								
								
								view.bloom(lyrics.getPoint(), lyrics.getTime()+startMoment, lyrics.isActive(), false);	
								
								
								toPlayLyricsList.remove(0);
								played=true;
							}
							break;
						default:
							break;
						}
						break;
					default:
						break;
					}
					
					if(!played) break;
				}
				

				

				//音符过期检测
				gameCtrl.checkOverdue((int) (System.currentTimeMillis()-startMoment));
				
				
				Thread.sleep(PAULING_INTERVAL);
			}
			
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
		public void stopRunning(){
			isRunning=false;
		}
	}
	//---------------------------------------------------------
//-------------------------------------------------------------
//Activity生命周期相关
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		pause();
	}

	@Override
	protected void onRestart() {
		// TODO Auto-generated method stub
		super.onRestart();
		resume();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		viewCtrl.updateTopActivity(this);
	}

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
	}
//--------------------------------------------------------
	
	//私有方法    
		private void initService() {
			gameCtrl = CtrlServiceProvider.getGameCtrlService();
			gameCtrl.setView(view);
			gameCtrl.setActivity(this);
			gameCtrl.reset();
			gameModel = ModelServiceProvider.getGameSystemService();
			viewCtrl = ViewServiceProvider.getViewService();
		}
		private void initUIComponent() {
			// TODO Auto-generated method stub
			
			
			pauseButton=new YButton();
			pauseButton.setBounds(750, 0, 50, 50);
			pauseButton.setBgp_pressed(BitmapFactory.decodeResource(getResources(), R.drawable.game_pause));
			pauseButton.setBgp_released(BitmapFactory.decodeResource(getResources(), R.drawable.game_pause));
			pauseButton.setOnClickListener(new OnClickListener() {
				
				public void OnClick() {
					// TODO Auto-generated method stub
					pause();
					quitButton.setVisible(true);
					resumeButton.setVisible(true);
					restartButton.setVisible(true);
					pauseButton.setVisible(false);
				}
			});
			buttonEventListener.registerButton(pauseButton);
			view.addYButton(pauseButton);
			
			quitButton=new YButton();
			quitButton.setBounds(500, 215, 50, 50);
			quitButton.setBgp_pressed(BitmapFactory.decodeResource(getResources(), R.drawable.game_back));
			quitButton.setBgp_released(BitmapFactory.decodeResource(getResources(), R.drawable.game_back));
			quitButton.setOnClickListener(new OnClickListener() {
				
				public void OnClick() {
					// TODO Auto-generated method stub
					//quit();
					jumpToResult();
				}
			});
			quitButton.setVisible(false);
			buttonEventListener.registerButton(quitButton);
			view.addYButton(quitButton);
			
			resumeButton=new YButton();
			resumeButton.setBounds(250, 215, 50, 50);
			resumeButton.setBgp_pressed(BitmapFactory.decodeResource(getResources(), R.drawable.game_continue));
			resumeButton.setBgp_released(BitmapFactory.decodeResource(getResources(), R.drawable.game_continue));
			resumeButton.setOnClickListener(new OnClickListener() {
				
				public void OnClick() {
					// TODO Auto-generated method stub
					resume();
					resumeButton.setVisible(false);
					quitButton.setVisible(false);
					restartButton.setVisible(false);
					pauseButton.setVisible(true);
				}
			});
			resumeButton.setVisible(false);
			buttonEventListener.registerButton(resumeButton);
			view.addYButton(resumeButton);
			
			restartButton = new YButton();
			restartButton.setBounds(375, 215, 50, 50);
			restartButton.setBgp_pressed(BitmapFactory.decodeResource(getResources(), R.drawable.game_restart));
			restartButton.setBgp_released(BitmapFactory.decodeResource(getResources(), R.drawable.game_restart));
			restartButton.setOnClickListener(new OnClickListener() {
				
				public void OnClick() {
					// TODO Auto-generated method stub
					Intent intent = new Intent(GameActivity.this, GameActivity.class);
					Intent intent2 = getIntent();
					intent.putExtra("lyricsVO", intent2.getSerializableExtra("lyricsVO"));
					intent.putExtra("musicVO", intent2.getSerializableExtra("musicVO"));
					viewCtrl.jumpTo(intent);
					
					resumeButton.setVisible(false);
					quitButton.setVisible(false);
					restartButton.setVisible(false);
					pauseButton.setVisible(true);
				}
			});
			restartButton.setVisible(false);
			buttonEventListener.registerButton(restartButton);
			view.addYButton(restartButton);
		}
		private void initEventListener(){
			buttonEventListener=new ButtonEventListener();
		}
		private void initMusicPlayer(){
			
			Intent intent = getIntent();		
			MusicVO musicVO = (MusicVO) intent.getSerializableExtra("musicVO");
			
			gameCtrl.setPlayingMusic(musicVO.getId());
			
			player =MediaPlayer.create(getApplicationContext(), Uri.parse(musicVO.getFilePath()));
			player.setLooping(false);
	        player.setOnCompletionListener(new OnCompletionListener() {
				
				public void onCompletion(MediaPlayer mp) {
					// TODO Auto-generated method stub
					
					finishGame();
				}
			});
		}
		private void initMomentControl(){
			toPlayLyricsList=new ArrayList<LyricsActionVO>();
			momentControlThread=new MomentControl();
		}
		private void init(){
			view=new GameView(this, this);
			setContentView(view);
			
			initService();
			initEventListener();
			initUIComponent();
		    initMusicPlayer();
		    initMomentControl();
		    initModel();
		    
		    
		}
	    private void initModel() {
			// TODO Auto-generated method stub
	    	Intent intent = getIntent();		
			LyricsVO lyricsVO = (LyricsVO) intent.getSerializableExtra("lyricsVO");
			

			gameCtrl.setPlayingLyrics(lyricsVO.getId());
			gameCtrl.loadResource();
		}


		private int inWhichPillar(float x,float y){
	    	int d;
	    	
	    	for(int i=0;i<UIparams.NUM_OF_PILLAR;i++){
	    		d=(int) Math.hypot(x-UIparams.center[i][0], y-UIparams.center[i][1]);
	    		if(d<UIparams.TOUCH_RANGE) return i;
	    	}
	    	
	    	return -1;
	    }
	    private void pause(){
	    	pauseMoment=System.currentTimeMillis();
	    	view.pause();
	    	player.pause();
	    	pause=true;
	    }
	    private void resume(){
	    	startMoment=startMoment+(System.currentTimeMillis()-pauseMoment);
	    	view.resume(System.currentTimeMillis()-pauseMoment);
	    	player.seekTo((int)(System.currentTimeMillis()-startMoment));
	    	player.start();
	    	pause=false;
	    }
	    private void quit(){
	    	
	    	gameCtrl.quit();
	    	
	    	//跳转到音乐列表界面
	    }
	    public void start(){
	    	startMoment=System.currentTimeMillis();
	    	player.start();
	    	momentControlThread.start();
	    }
	    private void finishGame(){
	    	gameCtrl.finishGame();
	    	jumpToResult();
	    }
	    private void jumpToResult(){
	    	Intent intent = new Intent(this, PlayOverActivity.class);
	    	intent.putExtra("score", gameModel.getScore());
	    	intent.putExtra("accuracy", gameModel.getAverageAccuracy());
	    	intent.putExtra("maxCombo", gameModel.getMaxCombo());
	    	intent.putExtra("level", gameModel.getLevel());
	    	
	    	Intent intent1 = getIntent();		
			LyricsVO lyricsVO = (LyricsVO) intent1.getSerializableExtra("lyricsVO");
			MusicVO musicVO = (MusicVO) intent1.getSerializableExtra("musicVO");
			
			intent.putExtra("lyricsVO", lyricsVO);
			intent.putExtra("musicVO", musicVO);
			
			
	    	viewCtrl.jumpTo(intent);
	    	
	    }


		public void updateScore() {
			// TODO Auto-generated method stub
			view.updateScore(gameModel.getScore());
			
		}


		public void updateCombo() {
			// TODO Auto-generated method stub
			view.updateCombo(gameModel.getCombo());
		}
	    
}
